/*
 * busca.c
 *
 *  Created on: Jul 5, 2011
 *      Author: tualibano
 */

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>

#include "structs.h"
#include "configurar.h"
#include "menu.h"
#include "busca.h"
#include "arquivo.h"
#include "Conectar.h" ////////////////////

int buscarnarede(char *string) {

    // envia via udp para todas as maquinas vizinhas
    struct sockaddr_in ipremoto;
    int socketremoto, porta;
    unsigned int iplen = sizeof (struct sockaddr_in);
    char buffer[512], ip[16];

    int cont = 0;
    porta = 5001;
    Vizinho v0;
    ZerarVizinho(&v0);

    TabelaVizinhos *ctabela;
    ctabela = tabela_vizinhos;

    
    while (ctabela != NULL) {
        while (cont < CAPACIDADE_TABELA) {
            if (!ComparaVizinho(&ctabela->Vizinhos[cont], &v0))
                break;
            sprintf(buffer, "busca:%s:%s:%s:5001:5001", string, string, iplocal);
            strcpy(ip, ctabela->Vizinhos[cont].Ip);
            if ((socketremoto = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
                perror("socket");

            ipremoto.sin_family = AF_INET;
            ipremoto.sin_port = htons(porta);
            ipremoto.sin_addr.s_addr = inet_addr(ip);
            bzero(&(ipremoto.sin_zero), 8);
            sendto(socketremoto, buffer, 128, 0, (struct sockaddr*) &ipremoto,
                    iplen);
            cont++;
        }
        cont = 0;
        ctabela = ctabela->ProximoBloco;
    }

   // printf("fazendo a busca com o buffer: %s\n", string);
    //
    // "busca":nome:id:ip_local
    return 0;
}

int buscahandler(char *string) {

    // string = buffer com a busca;
    struct sockaddr_in ipremoto;
    int socketremoto, porta;
    unsigned int iplen = sizeof (struct sockaddr_in);
    char buffer[512], ip[16], outrastring[128];
    strcpy(outrastring, string);
    int cont = 0;
    porta = 5001;
    Vizinho v0;
    ZerarVizinho(&v0);

    TabelaVizinhos *ctabela;
    ctabela = tabela_vizinhos;

    char *palavrabuscada;
    char *idbusca;
    char *ipsearcher;
    char *portatcp;
    char *portaudp;

    strtok(string, ":");
    idbusca = strtok(NULL, ":");
    palavrabuscada = strtok(NULL, ":");
    ipsearcher = strtok(NULL, ":");
    portatcp = strtok(NULL, ":");
    portaudp = strtok(NULL, ":");

    printf(
            "Busca:\nPalavra Buscada: %s\nIp solicitante: %s\nportatcp: %s\nporta udp: %s\n",
            palavrabuscada, ipsearcher, portatcp, portaudp);

    //se a busca nao passou por aqui ela manda para todos os vizinhos e entao faz a busca local

    if (passeiporaqui(&registrobusca, idbusca, ipsearcher, portatcp, portaudp) == 0) {

     //   printf("Chegou depois do Passei por aqui");

        while (ctabela != NULL) {
            while (cont < CAPACIDADE_TABELA) {
                if (!ComparaVizinho(&ctabela->Vizinhos[cont], &v0))
                    break;
                sprintf(buffer, "%s", outrastring);
                strcpy(ip, ctabela->Vizinhos[cont].Ip);
                if ((socketremoto = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))
                        == -1)
                    perror("socket");

                ipremoto.sin_family = AF_INET;
                ipremoto.sin_port = htons(porta);
                ipremoto.sin_addr.s_addr = inet_addr(ip);
                bzero(&(ipremoto.sin_zero), 8);
                sendto(socketremoto, buffer, 512, 0,
                        (struct sockaddr*) &ipremoto, iplen);
                cont++;
            }
            cont = 0;
            ctabela = ctabela->ProximoBloco;
        }

       // printf("\nmandou para todo mundo");
        puts(outrastring);
        fflush(stdout);
        getchar();
        puts(string);
        buscalocal(outrastring);

    }



    // tratamento // "busca":nome:id:ip_local //

    // se nunca recebeu essa busca: inseretabela();

    //buscar localmente o arquivo.
    // nome do arquivo
    // "busca":nome:id:ip_local
    // busca na rede de novo;
    return 0;
}

int criatabela(busca_individual **tabela) {
    busca_individual *ntabela;
    int contador = 0;

    ntabela = (busca_individual *) malloc(TAM_REG_BUSCA * sizeof (busca_individual));

    (*tabela) = ntabela;
    for (; contador < TAM_REG_BUSCA; contador++) {
        zerarbuscaind(&ntabela[contador]);
    }

    return 0;
}

int zerarbuscaind(busca_individual *elemento) {
    strcpy(elemento->nomebusca, "");
    ZerarVizinho(&(elemento->searcher));
    return 0;
}

int printregtabela(busca_individual **tabela) {
    busca_individual *atabela = *tabela;
    printf("\ntabela de registro de busca:");
    int contador;

    for (contador = 0; contador < TAM_REG_BUSCA; contador++) {
        printf("\n %s: %s: %d", atabela[contador].nomebusca, atabela[contador].searcher.Ip,
                atabela[contador].searcher.PortaTcp);
    }

    printf("\nfim print tabela");
    return 0;
}

int passeiporaqui(busca_individual **tabela, char *idbuscado, char *ipenviado,
        char *portatcp, char *portaudp) {
    Vizinho viz;
    ZerarVizinho(&viz);
    busca_individual *ctabela = *tabela;

    strcpy(viz.Ip, ipenviado);
    viz.PortaTcp = atoi(portatcp);
    viz.PortaUdp = atoi(portaudp);


   // printf("\nChegou no Passei Por aqui\n");
    if (buscaregtabela(&ctabela, idbuscado, ipenviado, portatcp, portaudp) == 0) {
        //se a busca ja foi enviada, termina a busca
     //   printf("\nFoi depois do buscaregtabela\n");
        return 1;
    } else {
        //se a busca nao foi enviada, insere na tabela e retorna 0
        inseretabela(tabela, idbuscado, viz);
        printregtabela(&ctabela);
       // printf("\nFoi no else buscaregtabela\n");
        return 0;
    }

}

int buscaregtabela(busca_individual **tabela, char *nomebusca, char *ipenviado,
        char *portatcp, char *portaudp) {

    Vizinho viz;
    ZerarVizinho(&viz);
    int contador = 0;
    busca_individual *ctabela = *tabela;

 //   printf("\nFoi no buscaregtabela\n");

    strcpy(viz.Ip, ipenviado); // strcpy
    viz.PortaTcp = atoi(portatcp);
    viz.PortaUdp = atoi(portaudp);

  //  printf("\nVai entrar no for buscaregtabela\n");
    for (; contador < TAM_REG_BUSCA; contador++) {

    //    printf("\nVai entrar no if buscaregtabela\n");
        if (!ComparaVizinho(&(ctabela[contador].searcher), &viz) && !strcmp(nomebusca,
                ctabela[contador].nomebusca)) {
            //se retorna 0 significa que ja existe
    //        printf("\nFoi no while buscaregtabela\n");
            return 0;
        }
    }
    return 1; ///
}

int inseretabela(busca_individual **tabela, char *nomebusca, Vizinho vizinho) {

    //printf("\nvai alocar tabela inseretabela");

    busca_individual *tab = *tabela;

    //printf("\nvai entrar no while inseretabela");

    int cont = 0;

    while (strcmp(tab[cont].nomebusca, "")) { ////
        cont++;
    }

    //printf("\nsaiu do while");

    strcpy(tab[cont].nomebusca, nomebusca);
    tab[cont].searcher.PortaTcp = vizinho.PortaTcp;
    tab[cont].searcher.PortaUdp = vizinho.PortaUdp;
    strcpy(tab[cont].searcher.Ip, vizinho.Ip);

    //printf("\ntudo esta nos conformes - por enquanto");

    return 0;
}

int removetabela(busca_individual *, char *nomebusca, Vizinho *);
